import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

/**
 * The dialog used to select the pre-tasks of a task.
 * 
 * @author zhongnanhai
 *
 */
public class PretasksDialog extends Dialog{
	/**Current edited task.*/
	private Task task;
	/**All of the tasks.*/
	private List<Task> tasks = new ArrayList<Task>();
	/**The pre-tasks this dialog will return.*/
	private ArrayList<Task> pretasks = new ArrayList<Task>();
	/**
	 * The constructor with a default style.
	 * @param parent its parent window
	 */
	public PretasksDialog(Shell parent){
		this(parent,SWT.DIALOG_TRIM | SWT.CLOSE);
	}
	/**
	 * The constructor of PretasksDialog.
	 * 
	 * @param parent its parent window
	 * @param style its specific style
	 */
	public PretasksDialog(Shell parent, int style) {
		super(parent, style);
		// TODO Auto-generated constructor stub
	}
	/**
	 * Set the current edited task.
	 * 
	 * @param task current Task object
	 */
	public void setTask(Task task){
		this.task = task;
	}
	/**
	 * Set the tasks the this dialog will show, and the pre-conditions between tasks
	 * would be used
	 * 
	 * @param tasks all of the tasks
	 */
	public void setTasks(ArrayList<Task> tasks){
		this.tasks = tasks;
	}
	/**
	 * The open function of a dialog class
	 * @return the pretasks list
	 */
	public ArrayList<Task> open(){
		Shell shell = new Shell(getParent(),getStyle());
		shell.setText("Select Pre-tasks");
		createContents(shell);
		shell.pack();
		int x = getParent().getBounds().x + (getParent().getBounds().width - shell.getBounds().width)/2;
		int y = getParent().getBounds().y + (getParent().getBounds().height - shell.getBounds().height)/2;
		shell.setLocation(x,y);
		shell.open();
		Display display = getParent().getDisplay();
		while(!shell.isDisposed()){
			if(display.readAndDispatch())
				display.sleep();
		}
		return pretasks;
	}
	/**
	 * Check if there exists a circle in the task graph, which means a task will be
	 * completed before another task that depends on its completion. If the situation
	 * occur, then the user may set a wrong pre orders.
	 * @param pretasks current selected pre-tasks
	 * @param return good condition,true;else false;
	 */
	private boolean check(List<Task> pretasks){
		if(pretasks.size()>0){
			if(pretasks.contains(task)){
				return false;
			}else{
				for(Task pretask:pretasks){
					if(!check(pretask.getPreTasks()))
						return false;
				}
			}
		}
		return true;
	}
	/**
	 * Create all of the contents/controls of this dialog.
	 * @param shell the dialog window
	 */
	private void createContents(final Shell shell){
		shell.setLayout(new FillLayout());
		final Table taskList = new Table(shell,SWT.BORDER | SWT.CHECK);
		for(int i = 0;i<tasks.size();i++){
			Task t = tasks.get(i);
			TableItem item = new TableItem(taskList,SWT.NONE);
			item.setText(t.getName());
			if(task.getPreTasks().contains(t))
				item.setChecked(true);
			else 
				item.setChecked(false);
		}
		//add actions
		shell.addDisposeListener(new DisposeListener(){
			@Override
			public void widgetDisposed(DisposeEvent e) {
				// TODO Auto-generated method stub
				ArrayList<Task> temp = new ArrayList<Task>();
				for(int i = 0 ;i<taskList.getItemCount();i++){
					if(taskList.getItem(i).getChecked()){
						temp.add(tasks.get(i));
					}
				}
				if(!check(temp)){
					Utilities.showMessage(shell,SWT.ICON_ERROR,"Your selection may cause an interdependence between the tasks,please check again.");
					pretasks = null;//if wrong,return null
					return;
				}else{
					pretasks = temp;
				}
			}
			
		});
	}
}
